package cn.xo68.boot.auth.server.token;

import cn.xo68.boot.auth.server.domain.OauthClient;
import cn.xo68.boot.auth.server.domain.OauthUser;
import cn.xo68.boot.auth.server.service.OauthClientService;
import cn.xo68.boot.auth.server.service.OauthUserService;
import cn.xo68.core.util.StringTools;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;

/**
 * 令牌申请审核抽象实现
 * @author wuxie
 * @date 2018-8-10
 */
public abstract class AbstractTokenRequestCheck implements TokenRequestCheck {

    @Autowired
    private OauthClientService oauthClientService;

    @Autowired
    private OauthUserService oauthUserService;

    private OAuthTokenRequest oAuthTokenRequest;

    @Override
    public OAuthTokenRequest getOAuthTokenRequest() {
        return oAuthTokenRequest;
    }

    @Override
    public void setOAuthTokenRequest(OAuthTokenRequest oAuthTokenRequest) {
        this.oAuthTokenRequest = oAuthTokenRequest;
    }

    @Override
    public OauthUserService getOauthUserService() {
        return oauthUserService;
    }

    @Override
    public TokenRequestCheckedResult check()  throws OAuthProblemException{
        TokenRequestCheckedResult result=new TokenRequestCheckedResult();
        OauthClient oauthClient=this.checkClientDetail(false);

        //判断是否允许此模式
        String[] grantTypes=StringTools.tokenizeToStringArray(oauthClient.getAuthorizedGrantTypes(),",");
        boolean support= Arrays.stream(grantTypes).anyMatch((str)->{
            return getOAuthTokenRequest().getGrantType().equalsIgnoreCase(str);
        });
        if(!support){
            throw OAuthProblemException.error("申请令牌异常","应用不支持此模式");
        }


        result.setOauthClient(oauthClient);
        OauthUser oauthUser=this.checkCredentials();
        result.setOauthUser(oauthUser);
        return result;
    }

    @Override
    public OauthClient checkClientDetail(boolean checkSecret) throws OAuthProblemException {
        OauthClient oauthClient = oauthClientService.get(oAuthTokenRequest.getClientId());
        if(oauthClient ==null){
            throw OAuthProblemException.error("参数异常","client_id不合法");
        }
        if(checkSecret && !oauthClient.getClientSecret().equals(oAuthTokenRequest.getClientSecret())){
            throw OAuthProblemException.error("参数异常","client_id或ClientSecret不合法");
        }
        return oauthClient;
    }

    /**
     * 验证令牌申请资格
     * @return
     * @throws OAuthProblemException
     */
    @Override
    public abstract OauthUser checkCredentials() throws OAuthProblemException ;
}
